﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ASPMVCUtil.Helpers.Html.Grid;
using System.Reflection;
using OfficeOpenXml;

namespace ASPMVCUtil.ExcelExporter
{
    public class ExcelColumn<TModel>
    {
        public string PropertyName { get; protected set; }
        public string Header { get; protected set; }
        public string SubpropertyName { get; protected set; }
        public virtual GridCellTemplate<TModel> Template { get; protected set; }

        public static ExcelColumn<TModel> create(string propertyName)
        {
            return new ExcelColumn<TModel>(propertyName, propertyName, null, null);
        }

        public static ExcelColumn<TModel> create(string propertyName, string header, GridCellTemplate<TModel> template = null)
        {
            return new ExcelColumn<TModel>(propertyName, header, null, template);
        }

        public static ExcelColumn<TModel> create(string propertyName, string header, string subpropertyName, GridCellTemplate<TModel> template = null)
        {
            return new ExcelColumn<TModel>(propertyName, header, subpropertyName, template);
        }

        public ExcelColumn(string propertyName, string header, string subpropertyName, GridCellTemplate<TModel> template)
        {

            PropertyName = propertyName;
            Header = header;
            SubpropertyName = subpropertyName;
            if (template == null)
            {
                Template = new ExcelPlantillaCelda<TModel>();
            }
            else
            {
                Template = template;
            }
        }

        /// <summary>
        /// Obtiene el valor formateado de una celda de la columna a partir de un registro. Además adjunta a la ruta para acciones AJAX el valor limpio de la celda
        /// </summary>
        /// <param name="registro"></param>
        /// <returns></returns>
        public string ObtenerValor(TModel registro)
        {
            //Obtengo la propiedad de la columna para el registro
            string[] splitProperty = PropertyName.Split('.');
            PropertyInfo propiedad = null;
            object valorCampo = null;
            foreach (string propertyName in splitProperty)
            {
                if (propertyName.Equals(splitProperty[0]))
                    propiedad = registro.GetType().GetProperty(propertyName);
                else if (valorCampo == null)
                    break;
                else
                    propiedad = valorCampo.GetType().GetProperty(propertyName);
                if (propiedad == null)
                    throw new ArgumentException("La propiedad " + PropertyName + " de " + propiedad.Name + " indicada en la columna no existe en el tipo indicado, revise que no sea un error tipográficor");
                if (propiedad.CanRead)
                {
                    if (propertyName.Equals(splitProperty[0]))
                        valorCampo = propiedad.GetValue(registro, null);
                    else
                        valorCampo = propiedad.GetValue(valorCampo, null);
                }
                else
                    throw new ArgumentException("La propiedad " + PropertyName + " de " + propiedad.Name + " no se puede leer");
            }
            return Template.Draw(valorCampo, registro);
        }

        internal void SetStyle(ExcelRange excelRange)
        {
            Template.SetStyle(excelRange);
        }
    }
}
